package com.example.origin.spider.service;

import com.example.origin.spider.webmagic.ChromeProcessor;
import com.example.origin.spider.webmagic.SimpleChromeDownloader;
import com.example.origin.spider.properties.ProcessorProperties;
import com.example.origin.spider.utils.OcrUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.springframework.stereotype.Service;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.ResultItems;
import us.codecraft.webmagic.Task;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Function;

@Slf4j
@Service("zxgk-court")
public final class ZxgkCourtProcessor extends ChromeProcessor {

    private static final String REGEX = "^[a-zA-Z0-9]{4}$";


    @Override
    public void process(ResultItems resultItems, Task task) {
        System.out.println("get page: " + resultItems.getRequest().getUrl());
        for (Map.Entry<String, Object> entry : resultItems.getAll().entrySet()) {
            System.out.println(entry.getKey() + ":\t" + entry.getValue());
        }
    }

    @Override
    @SneakyThrows
    public void process(Page page, ProcessorProperties properties) {

        if (page.getUrl().get().contains("ip.chaxunjiao.com")) {
            page.putField("ip", page.getHtml().css("h3").get());
            return;
//        } else if (page.getUrl().get().contains("http://zxgk.court.gov.cn/shixin")){
//            String s = page.getHtml().get();
//            System.out.println(s);
//            return;
        } else {
//            if (page.getUrl().get().contains("http://zxgk.court.gov.cn")) {
//
//            }else
            if (page.getUrl().get().contains("http://zxgk.court.gov.cn")) {

                SimpleChromeDownloader downloader = (SimpleChromeDownloader) page.getRequest().getDownloader();
                WebDriver webDriver = downloader.getWebDriver();

                // 执行JavaScript代码来打开新Tab
                // 注意：这里使用window.open()方法来打开新Tab，并指定URL
                ((JavascriptExecutor) webDriver).executeScript("window.open('http://zxgk.court.gov.cn/waf_text_captcha');");
                webDriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

                code2Page(webDriver,(driver,flag)->{
                    // 获取所有窗口的句柄
                    Set<String> handles = driver.getWindowHandles();
                    String firstHandle = driver.getWindowHandle();
                    // 切换到新打开的Tab
                    for (String handle : handles) {
                        if (!handle.equals(firstHandle)) {
                            driver.switchTo().window(handle);
                            if (flag){
                                driver.navigate().refresh();
                            }
                        }
                    }
                    String code = getCode(driver);
                    driver.switchTo().window(firstHandle);
                    if (code==null) {
                        return;
                    }
                    WebElement input = driver.findElement(By.cssSelector(".code-input"));
                    input.sendKeys(code);
                    WebElement btn = driver.findElement(By.cssSelector(".code-btn"));
                    btn.click();
                    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
                },driver->{
                    List<WebElement> elements = driver.findElements(By.cssSelector(".code-btn"));
                    boolean flag = elements.stream().anyMatch(WebElement::isDisplayed);
                    if (!flag){
                        // 获取所有窗口的句柄
                        Set<String> handles = driver.getWindowHandles();
                        String firstHandle = driver.getWindowHandle();
                        // 切换到新打开的Tab
                        for (String handle : handles) {
                            if (!handle.equals(firstHandle)) {
                                driver.switchTo().window(handle).close();
                            }
                        }
                        driver.switchTo().window(firstHandle);
                        log.info("current Page Url: {}",driver.getCurrentUrl());
                    }
                    return flag;
                });

//                webDriver.findElement(By.cssSelector(".weblink .sxbzxr_nor")).click();
//                webDriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

                System.out.println();
                // 等待页面加载完成
//                Page newPage = downloader.newPage(page.getRequest());
//                Selectable links = newPage.getHtml().links();
//                for (String s : links.all()) {
//                    if (StringUtils.hasText(s.trim())) {
//                        System.out.println(s);
//                    }
//                }
//                Page newPage = downloader.newPage(page.getRequest());
//                Request request = newPage.getRequest().setUrl("http://zxgk.court.gov.cn/shixin");
//                page.addTargetRequest("http://zxgk.court.gov.cn/shixin");
                return;
            }
        }

        page.addTargetRequest("https://ip.chaxunjiao.com/");
    }

    private static void code2Page(WebDriver driver, BiConsumer<WebDriver,Boolean> consumer, Function<WebDriver,Boolean> function) {
        consumer.accept(driver,false);
        if (function.apply(driver)) {
            for (int i = 0; i < 10; i++) {
                if (!function.apply(driver)) {
                    break;
                }
                log.info("【验证码错误，第{}次重新填写】",i+1);
                consumer.accept(driver,true);
            }
        }
        if (function.apply(driver)) {
            // todo 告警
        }
    }

    @SneakyThrows
    private static String getCode(WebDriver driver) {
        String s = null;
        for (int i = 0; i < 10; i++) {
            //log.info("第{}次获取验证码",i+1);
            byte[] screenshotAs = ((ChromeDriver) driver).getScreenshotAs(OutputType.BYTES);
            TimeUnit.SECONDS.sleep(1);
            List<String> list = OcrUtil.verifyCodes(screenshotAs);
            Optional<String> first = list.stream().filter(e -> e.matches(REGEX)).findFirst();
            if (!first.isPresent()) {
                log.info("第{}次获取验证码，失败，页面刷新",i+1);
                driver.navigate().refresh();
                driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
            }else {
                s = first.get();
                break;
            }
        }
        return s;
    }
}
